home *** CD-ROM | disk | FTP | other *** search
/ Info-Mac 4 / Info_Mac IV CD-ROM (Pacific HiTech Inc.)(August 1994).iso / Development / Source / Macintosh Tracker Source / Tracker Client Folder / Core 18⁄March⁄1994 / CWindow.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-03-18  |  27.6 KB  |  1,143 lines  |  [TEXT/KAHL]

  1. /* CWindow.c */
  2.  
  3. #define COMPILING_CWINDOW_C
  4. #include "CWindow.h"
  5. #include "Memory.h"
  6. #include "CSack.h"
  7. #include "CApplication.h"
  8. #include "Compatibility.h"
  9. #include "MenuController.h"
  10.  
  11.  
  12. CWindow*                    ActiveWindow;
  13.  
  14. LongPoint                    ZeroPoint = {0,0};
  15.  
  16. #define MAXTEXTSIZING (32767)
  17.  
  18. #define DEBUGSCROLL(Rgn)  InvertRgn(Rgn); { long Start; Start = TickCount(); while ((signed long)TickCount() - Start < 4); } InvertRgn(Rgn);
  19.  
  20. /* setting this to 1 enables manual munging of the update region for the */
  21. /* scrollrect routines */
  22. #define DOTHENAUGHTY (0)
  23.  
  24. EXECUTE(static char GrafErrMsg[]
  25.     = {"CWindow drawing function called while other window's GrafPort was active."};)
  26.  
  27.  
  28. /* */        CWindow::CWindow()
  29.     {
  30.         CSack*        Temp;
  31.  
  32.         OurKeyReceiver = NIL;
  33.         Temp = new CSack;
  34.         Temp->ISack(sizeof(CViewRect*),128);
  35.         ListOfWindowClients = Temp;
  36.         MyGrafPtr = NIL;
  37.         ZoomStatePartCode = inZoomOut; /* we start zoomed in */
  38.     }
  39.  
  40.  
  41. /* */        CWindow::~CWindow()
  42.     {
  43.         CViewRect*    Thang;
  44.  
  45.         ERROR(Initialized != True,PRERR(ForceAbort,
  46.             "CWindow::~CWindow called on uninitialized object."));
  47.         ListOfWindowClients->ResetScan();
  48.         while (ListOfWindowClients->GetNext(&Thang))
  49.             {
  50.                 Thang->Window = NIL;
  51.             }
  52.         delete ListOfWindowClients;
  53.         if (ActiveWindow == this)
  54.             {
  55.                 ActiveWindow = NIL;
  56.             }
  57.         DeleteMyGrafPtr();
  58.     }
  59.  
  60.  
  61. /* this creates the window record.  Override & call this last */
  62. void        CWindow::IWindow(LongPoint Start, LongPoint Extent, MyBoolean ModalFlag,
  63.                     MyBoolean GrowFlag, MyBoolean ZoomFlag)
  64.     {
  65.         Rect        ShortWhere;
  66.  
  67.         ERROR(Initialized == True,PRERR(ForceAbort,
  68.             "CWindow::IWindow called on already initialized object."));
  69.         EXECUTE(Initialized = True);
  70.         Modality = ModalFlag;
  71.         Growable = GrowFlag;
  72.         Zoomable = ZoomFlag;
  73.         Origin = ZeroPoint; /* this never changes, since the window is what everyone */
  74.         /* else references their origins from. */
  75.         MakeMyGrafPtr(Start,Extent);
  76.         IEnclosure(Start,Extent,this,NIL);
  77.         DoFindPosition();
  78.         VisRectStart = ZeroPoint;
  79.         VisRectExtent = Extent;
  80.         Origin = ZeroPoint;
  81.         SetWRefCon(MyGrafPtr,(long)this);
  82.     }
  83.  
  84.  
  85. /* user should override this & create his own MyWindowPtr */
  86. void        CWindow::MakeMyGrafPtr(LongPoint Start, LongPoint Extent)
  87.     {
  88.         Rect        BoundsRect;
  89.         short        WindowCode;
  90.  
  91.         ERROR(Initialized != True,PRERR(ForceAbort,
  92.             "CWindow::MakeMyGrafPtr called on uninitialized object."));
  93.         ERROR(MyGrafPtr!=NIL,PRERR(ForceAbort,
  94.             "CWindow::MakeMyGrafPtr called, but MyGrafPtr is not NIL."));
  95.         BoundsRect = RectOf(Start.x,Start.y,Start.x+Extent.x,Start.y+Extent.y);
  96.         if (Growable)
  97.             {
  98.                 if (Zoomable)
  99.                     {
  100.                         WindowCode = zoomDocProc;
  101.                     }
  102.                  else
  103.                     {
  104.                         WindowCode = documentProc;
  105.                     }
  106.             }
  107.          else
  108.             {
  109.                 if (Zoomable)
  110.                     {
  111.                         WindowCode = zoomNoGrow;
  112.                     }
  113.                  else
  114.                     {
  115.                         WindowCode = noGrowDocProc;
  116.                     }
  117.             }
  118.         MyGrafPtr = NewWindow(NIL,&BoundsRect,"\p",True,WindowCode,(void*)-1,
  119.             True,(long)this);
  120.         if (MyGrafPtr == NIL)
  121.             {
  122.                 PRERR(ForceAbort,"NewWindow failed to allocate memory.");
  123.             }
  124.     }
  125.  
  126.  
  127. void            CWindow::DeleteMyGrafPtr(void)
  128.     {
  129.         ERROR(MyGrafPtr==NIL,PRERR(ForceAbort,
  130.             "CWindow::DeleteMyGrafPtr called but MyGrafPtr is already NIL."));
  131.         DisposeWindow(MyGrafPtr);
  132.     }
  133.  
  134.  
  135. void            CWindow::DoUpdate(void)
  136.     {
  137.         ERROR(Initialized != True,PRERR(ForceAbort,
  138.             "CWindow::DoUpdate called on uninitialized object."));
  139.         ERROR(MyGrafPtr==NIL,PRERR(ForceAbort,
  140.             "CWindow::DoUpdate called but MyGrafPtr is already NIL."));
  141.         BeginUpdate(MyGrafPtr);  /* begin the process */
  142.         inherited::DoUpdate();
  143.         if (Growable)
  144.             {
  145.                 LongPoint            LocalExtent = {16,16};
  146.  
  147.                 SetUpPort();
  148.                 if (Suspended)
  149.                     {
  150.                         LDrawPicture(GetPic(EmptyGrowIconPictID),
  151.                             LongPointOf(Extent.x-15,Extent.y-15),LocalExtent);
  152.                     }
  153.                  else
  154.                     {
  155.                         LDrawPicture(GetPic(GrowIconPictID),
  156.                             LongPointOf(Extent.x-15,Extent.y-15),LocalExtent);
  157.                     }
  158.             }
  159.         EndUpdate(MyGrafPtr);  /* stop updating */
  160.     }
  161.  
  162.  
  163. void            CWindow::DoSuspend(void)
  164.     {
  165.         ERROR(Initialized != True,PRERR(ForceAbort,
  166.             "CWindow::DoSuspend called on uninitialized object."));
  167.         OurKeyReceiver = KeyReceiverViewRect;
  168.         if (KeyReceiverViewRect != NIL)
  169.             {
  170.                 KeyReceiverViewRect->RelinquishKeyReceivership();
  171.             }
  172.         if (Growable)
  173.             {
  174.                 LongPoint            LocalExtent = {16,16};
  175.  
  176.                 SetUpPort();
  177.                 LDrawPicture(GetPic(EmptyGrowIconPictID),
  178.                     LongPointOf(Extent.x-15,Extent.y-15),LocalExtent);
  179.             }
  180.         inherited::DoSuspend();
  181.         KeyReceiverViewRect = NIL;
  182.     }
  183.  
  184.  
  185. void            CWindow::DoResume(void)
  186.     {
  187.         ERROR(Initialized != True,PRERR(ForceAbort,
  188.             "CWindow::DoResume called on uninitialized object."));
  189.         if (Growable)
  190.             {
  191.                 LongPoint            LocalExtent = {16,16};
  192.  
  193.                 SetUpPort();
  194.                 LDrawPicture(GetPic(GrowIconPictID),
  195.                     LongPointOf(Extent.x-15,Extent.y-15),LocalExtent);
  196.             }
  197.         inherited::DoResume();
  198.         if (OurKeyReceiver != NIL)
  199.             {
  200.                 OurKeyReceiver->BecomeKeyReceiver();
  201.             }
  202.     }
  203.  
  204.  
  205. void            CWindow::SetDefaultKeyReceiver(CViewRect* TheReceiver)
  206.     {
  207.         ERROR(Initialized != True,PRERR(ForceAbort,
  208.             "CWindow::SetDefaultKeyReceiver called on uninitialized object."));
  209.         ERROR(!Suspended,PRERR(ForceAbort,
  210.             "CWindow::SetDefaultKeyReceiver attempted to set default key Receiver while not suspended."));
  211.         OurKeyReceiver = TheReceiver;
  212.     }
  213.  
  214.  
  215. /* track the go-away thing */
  216. void            CWindow::DoGoAway(Point GlobalStart)
  217.     {
  218.         ERROR(Initialized != True,PRERR(ForceAbort,
  219.             "CWindow::DoGoAway called on uninitialized object."));
  220.         ERROR(MyGrafPtr==NIL,PRERR(ForceAbort,
  221.             "CWindow::DoGoAway called but MyGrafPtr is already NIL."));
  222.         if (TrackGoAway(MyGrafPtr,GlobalStart))
  223.             {
  224.                 GoAway();
  225.             }
  226.     }
  227.  
  228.  
  229. /* override to provide a go-away check function */
  230. void            CWindow::GoAway(void)
  231.     {
  232.         ERROR(Initialized != True,PRERR(ForceAbort,
  233.             "CWindow::GoAway called on uninitialized object."));
  234.         DoMenuCommand(mFileClose);
  235.     }
  236.  
  237.  
  238. /* get the size constraints for the window */
  239. Rect        CWindow::GetConstraint(void)
  240.     {
  241.         Rect        Temp = {100,100,32767,32767};
  242.  
  243.         ERROR(Initialized != True,PRERR(ForceAbort,
  244.             "CWindow::GetConstraint called on uninitialized object."));
  245.         return Temp;
  246.     }
  247.  
  248.  
  249. LongPoint    CWindow::SnapToGrid(LongPoint NewWindowSize)
  250.     {
  251.         return NewWindowSize;
  252.     }
  253.  
  254.  
  255. void            CWindow::DoFindPosition(void)
  256.     {
  257.         Point        Delta = {0,0};
  258.  
  259.         ERROR(Initialized != True,PRERR(ForceAbort,
  260.             "CWindow::DoFindPosition called on uninitialized object."));
  261.         SetMyPort();
  262.         LocalToGlobal(&Delta); /* find top-left with respect to screen */
  263.         Start.x = Delta.h;
  264.         Start.y = Delta.v;
  265.     }
  266.  
  267.  
  268. void            CWindow::SetNewSize(LongPoint NewWindowSize)
  269.     {
  270.         LongPoint        DeltaExtent;
  271.         CViewRect*    Thang;
  272.  
  273.         ERROR(Initialized != True,PRERR(ForceAbort,
  274.             "CWindow::SetNewSize called on uninitialized object."));
  275.         DeltaExtent.x = NewWindowSize.x - Extent.x;
  276.         DeltaExtent.y = NewWindowSize.y - Extent.y;
  277.         Extent = NewWindowSize;
  278.         SizeWindow(MyGrafPtr,Extent.x,Extent.y,True);
  279.         DoFindPosition();
  280.         VisRectStart = ZeroPoint;
  281.         VisRectExtent = Extent;
  282.         Origin = ZeroPoint;
  283.         SetUpPort();
  284.         Window->LEraseRect(ZeroPoint,Extent);
  285.         Window->InvalidateLong(ZeroPoint,Extent);
  286.         ListOfObjects->ResetScan();
  287.         while (ListOfObjects->GetNext(&Thang))
  288.             {
  289.                 Thang->DoEnclosureResized(DeltaExtent);
  290.             }
  291.     }
  292.  
  293.  
  294. void            CWindow::DoGrow(Point GlobalStart)
  295.     {
  296.         long                Result;
  297.         Rect                Limits;
  298.  
  299.         ERROR(Initialized != True,PRERR(ForceAbort,
  300.             "CWindow::DoGrow called on uninitialized object."));
  301.         Limits = GetConstraint();
  302.         Result = GrowWindow(MyGrafPtr,GlobalStart,&Limits);
  303.         if (Result != 0)
  304.             {
  305.                 SetNewSize(SnapToGrid(LongPointOf(0x0000ffff & Result/*X coord*/,
  306.                     0x0000ffff & (Result >> 16)/*Ycoord*/)));
  307.             }
  308.     }
  309.  
  310.  
  311. void            CWindow::DoZoomIn(Point GlobalStart)
  312.     {
  313.         if (TrackBox(MyGrafPtr,GlobalStart,inZoomIn))
  314.             {
  315.                 ZoomIn();
  316.             }
  317.     }
  318.  
  319.  
  320. void            CWindow::DoZoomOut(Point GlobalStart)
  321.     {
  322.         if (TrackBox(MyGrafPtr,GlobalStart,inZoomOut))
  323.             {
  324.                 ZoomOut();
  325.             }
  326.     }
  327.  
  328.  
  329. void            CWindow::ZoomIn(void)
  330.     {
  331.         ZoomStatePartCode = inZoomOut; /* opposite--state BEFORE THIS zoom occurs */
  332.         SetUpPort();
  333.         LEraseRect(ZeroPoint,Extent);
  334.         InvalidateLong(ZeroPoint,Extent);
  335.         ZoomWindow(MyGrafPtr,inZoomIn,False);
  336.         SetNewSize(SnapToGrid(
  337.             LongPointOf(MyGrafPtr->portRect.right - MyGrafPtr->portRect.left,
  338.             MyGrafPtr->portRect.bottom - MyGrafPtr->portRect.top)));
  339.     }
  340.  
  341.  
  342. void            CWindow::ZoomOut(void)
  343.     {
  344.         ZoomStatePartCode = inZoomIn; /* opposite--state BEFORE THIS zoom occurs */
  345.         SetUpPort();
  346.         LEraseRect(ZeroPoint,Extent);
  347.         InvalidateLong(ZeroPoint,Extent);
  348.         ZoomWindow(MyGrafPtr,inZoomOut,False);
  349.         SetNewSize(SnapToGrid(
  350.             LongPointOf(MyGrafPtr->portRect.right - MyGrafPtr->portRect.left,
  351.             MyGrafPtr->portRect.bottom - MyGrafPtr->portRect.top)));
  352.     }
  353.  
  354.  
  355. void            CWindow::DoDrag(Point GlobalStart)
  356.     {
  357.         Rect                BoundsRect;
  358.         RgnHandle        BoundsRegion;
  359.  
  360.         ERROR(Initialized != True,PRERR(ForceAbort,
  361.             "CWindow::DoDrag called on uninitialized object."));
  362.         BoundsRegion = GetGrayRgn();
  363.         BoundsRect = (**BoundsRegion).rgnBBox;
  364.         InsetRect(&BoundsRect,4,4);
  365.         DragWindow(MyGrafPtr,GlobalStart,&BoundsRect);
  366.         DoFindPosition();
  367.     }
  368.  
  369.  
  370. void            CWindow::DoMouseDown(MyEventRec Event)
  371.     {
  372.         ERROR(Initialized != True,PRERR(ForceAbort,
  373.             "CWindow::DoMouseDown called on uninitialized object."));
  374.         if (ActiveWindow == this)
  375.             {
  376.                 inherited::DoMouseDown(Event);
  377.             }
  378.          else
  379.             {
  380.                 SelectWindow(MyGrafPtr);
  381.             }
  382.     }
  383.  
  384.  
  385. void            CWindow::BecomeActiveWindow(void)
  386.     {
  387.         ERROR(Initialized != True,PRERR(ForceAbort,
  388.             "CWindow::BecomeActiveWindow called on uninitialized object."));
  389.         if ((ActiveWindow == NIL) || ((ActiveWindow != NIL)
  390.             && (ActiveWindow->Modality == ModelessWindow)))
  391.             {
  392.                 SelectWindow(MyGrafPtr);
  393.             }
  394.     }
  395.  
  396.  
  397. void            CWindow::RegisterClient(CViewRect* Client)
  398.     {
  399.         ERROR(Initialized != True,PRERR(ForceAbort,
  400.             "CWindow::RegisterClient called on uninitialized object."));
  401.         ListOfWindowClients->PushElement(&Client);
  402.     }
  403.  
  404.  
  405. void            CWindow::DeregisterClient(CViewRect* Client)
  406.     {
  407.         ERROR(Initialized != True,PRERR(ForceAbort,
  408.             "CWindow::DeregisterClient called on uninitialized object."));
  409.         ListOfWindowClients->KillElement(&Client);
  410.     }
  411.  
  412.  
  413. /********************************************************************************/
  414. /* LongRect versions of QuickDraw routines */
  415.  
  416.  
  417. void            CWindow::SetMyPort(void)
  418.     {
  419.         Rect            Temp;
  420.  
  421.         if (thePort != MyGrafPtr)
  422.             {
  423.                 SetPort(MyGrafPtr);
  424.             }
  425.         ClipStart = ZeroPoint;
  426.         ClipExtent = Extent;
  427.         ResetPen();
  428.         EXECUTE(SetText(systemFont,outline,srcOr,36,0));
  429.     }
  430.  
  431.  
  432. void            CWindow::SetOrigin(LongPoint TheOrigin)
  433.     {
  434.         DrawingOrigin = TheOrigin;
  435.     }
  436.  
  437.  
  438. void            CWindow::SetClipRect(LongPoint Start, LongPoint Extent)
  439.     {
  440.         Rect                Temp;
  441.  
  442.         ERROR(MyGrafPtr != thePort,PRERR(ForceAbort,GrafErrMsg));
  443.         Start.x += DrawingOrigin.x;
  444.         Start.y += DrawingOrigin.y;
  445.         SectLongRect(ClipStart,ClipExtent,Start,Extent,&ClipStart,&ClipExtent);
  446.         Temp.left = ClipStart.x;
  447.         Temp.top = ClipStart.y;
  448.         Temp.right = ClipStart.x + ClipExtent.x;
  449.         Temp.bottom = ClipStart.y + ClipExtent.y;
  450.         ClipRect(&Temp);
  451.     }
  452.  
  453.  
  454. void            CWindow::SetPen(short Width, short Height, short Mode, Pattern ThePattern)
  455.     {
  456.         ERROR(MyGrafPtr != thePort,PRERR(ForceAbort,GrafErrMsg));
  457.         PenSize(Width,Height);
  458.         PenMode(Mode);
  459.         PenPat(ThePattern);
  460.     }
  461.  
  462.  
  463. void            CWindow::ResetPen(void)
  464.     {
  465.         ERROR(MyGrafPtr != thePort,PRERR(ForceAbort,GrafErrMsg));
  466.         PenNormal();
  467.     }
  468.  
  469.  
  470. void            CWindow::SetPenMode(short Mode)
  471.     {
  472.         ERROR(MyGrafPtr != thePort,PRERR(ForceAbort,GrafErrMsg));
  473.         PenMode(Mode);
  474.     }
  475.  
  476.  
  477. void            CWindow::SetPenSize(short Width, short Height)
  478.     {
  479.         ERROR(MyGrafPtr != thePort,PRERR(ForceAbort,GrafErrMsg));
  480.         PenSize(Width,Height);
  481.     }
  482.  
  483.  
  484. void            CWindow::SetGreyishTextOr(void)
  485.     {
  486.         ERROR(MyGrafPtr != thePort,PRERR(ForceAbort,GrafErrMsg));
  487.         ResetPen();
  488.         PenMode(srcCopy);
  489.         PenPat(gray);
  490.         TextMode(grayishTextOr);
  491.     }
  492.  
  493.  
  494. void            CWindow::DrawLine(LongPoint Start, LongPoint Extent)
  495.     {
  496.         Rect        Place;
  497.  
  498.         ERROR(MyGrafPtr != thePort,PRERR(ForceAbort,GrafErrMsg));
  499.         if (LongRectToShort(Start,Extent,&Place))
  500.             {
  501.                 MoveTo(Place.left,Place.top);
  502.                 LineTo(Place.right,Place.bottom);
  503.             }
  504.     }
  505.  
  506.  
  507. void            CWindow::SetText(short FontID, Style Face, short Mode, short PointSize, Fixed Space)
  508.     {
  509.         ERROR(MyGrafPtr != thePort,PRERR(ForceAbort,GrafErrMsg));
  510.         TextFont(FontID);
  511.         TextFace(Face);
  512.         TextMode(Mode);
  513.         TextSize(PointSize);
  514.         SpaceExtra(Space);
  515.     }
  516.  
  517.  
  518. void            CWindow::SetTextMode(short Mode)
  519.     {
  520.         ERROR(MyGrafPtr != thePort,PRERR(ForceAbort,GrafErrMsg));
  521.         TextMode(Mode);
  522.     }
  523.  
  524.  
  525. void            CWindow::LTextBox(LongPoint Start, LongPoint Extent, Handle Text, short Justification)
  526.     {
  527.         Rect        Temp;
  528.  
  529.         ERROR(MyGrafPtr != thePort,PRERR(ForceAbort,GrafErrMsg));
  530.         LongRectToShort(Start,Extent,&Temp);
  531.         HLock(Text);
  532.         TextBox(*Text,HandleSize(Text),&Temp,(short)Justification);
  533.         HUnlock(Text);
  534.     }
  535.  
  536.  
  537. void            CWindow::LDrawText(LongPoint Start, LongPoint Extent, Handle Text, short Justification)
  538.     {
  539.         Rect            Temp;
  540.         short            NumPixels;
  541.         short            YPos;
  542.         FontInfo    FInfo;
  543.  
  544.         ERROR(MyGrafPtr != thePort,PRERR(ForceAbort,GrafErrMsg));
  545.         LongRectToShort(Start,Extent,&Temp);
  546.         GetFontInfo(&FInfo);
  547.         HLock(Text);
  548.         NumPixels = TextWidth(*Text,0,HandleSize(Text));
  549.         YPos = (Temp.top+Temp.bottom-(FInfo.ascent+FInfo.descent+FInfo.leading))/2
  550.             + FInfo.ascent + FInfo.leading;
  551.         switch (Justification)
  552.             {
  553.                 case JustifyLeft:
  554.                     MoveTo(Temp.left,YPos);
  555.                     break;
  556.                 case JustifyCenter:
  557.                     MoveTo((Temp.left+Temp.right-NumPixels)/2,YPos);
  558.                     break;
  559.                 case JustifyRight:
  560.                     MoveTo((Temp.right-NumPixels),YPos);
  561.                     break;
  562.                 default:
  563.                     EXECUTE(PRERR(AllowResume,
  564.                         "Illegal text justification code passed to CWindow::LDrawText."));
  565.                     break;
  566.             }
  567.         DrawText(*Text,0,HandleSize(Text));
  568.         HUnlock(Text);
  569.     }
  570.  
  571.  
  572. void            CWindow::LDrawTextPtr(LongPoint Start, LongPoint Extent, char* Text,
  573.                         long Length, short Justification)
  574.     {
  575.         Rect            Temp;
  576.         short            NumPixels;
  577.         short            YPos;
  578.         FontInfo    FInfo;
  579.  
  580.         ERROR(MyGrafPtr != thePort,PRERR(ForceAbort,GrafErrMsg));
  581.         LongRectToShort(Start,Extent,&Temp);
  582.         GetFontInfo(&FInfo);
  583.         NumPixels = TextWidth(Text,0,Length);
  584.         YPos = (Temp.top+Temp.bottom-(FInfo.ascent+FInfo.descent+FInfo.leading))/2
  585.             + FInfo.ascent + FInfo.leading;
  586.         switch (Justification)
  587.             {
  588.                 case JustifyLeft:
  589.                     MoveTo(Temp.left,YPos);
  590.                     break;
  591.                 case JustifyCenter:
  592.                     MoveTo((Temp.left+Temp.right-NumPixels)/2,YPos);
  593.                     break;
  594.                 case JustifyRight:
  595.                     MoveTo((Temp.right-NumPixels),YPos);
  596.                     break;
  597.                 default:
  598.                     EXECUTE(PRERR(AllowResume,
  599.                         "Illegal text justification code passed to CWindow::LDrawText."));
  600.                     break;
  601.             }
  602.         DrawText(Text,0,Length);
  603.     }
  604.  
  605.  
  606. long            CWindow::LMeasureText(char* Text, long NumChars)
  607.     {
  608.         long            CurrentLinePixels;
  609.         long            IndexIntoBuffer;
  610.  
  611.         CurrentLinePixels = 0;
  612.         IndexIntoBuffer = 0;
  613.         while (NumChars > 0)
  614.             {
  615.                 if (NumChars > MAXTEXTSIZING)
  616.                     {
  617.                         CurrentLinePixels += TextWidth(&(Text[IndexIntoBuffer]),0,MAXTEXTSIZING);
  618.                         NumChars -= MAXTEXTSIZING;
  619.                         IndexIntoBuffer += MAXTEXTSIZING;
  620.                     }
  621.                  else
  622.                     {
  623.                         CurrentLinePixels += TextWidth(&(Text[IndexIntoBuffer]),0,NumChars);
  624.                         NumChars = 0;
  625.                     }
  626.             }
  627.         return CurrentLinePixels;
  628.     }
  629.  
  630.  
  631. void            CWindow::LDrawPicture(PicHandle ThePicture, LongPoint Start, LongPoint Extent)
  632.     {
  633.         Rect        Temp;
  634.  
  635.         ERROR(MyGrafPtr != thePort,PRERR(ForceAbort,GrafErrMsg));
  636.         if (LongRectToShort(Start,Extent,&Temp))
  637.             {
  638.                 DrawPicture(ThePicture,&Temp);
  639.             }
  640.     }
  641.  
  642.  
  643. void            CWindow::LFrameRect(LongPoint Start, LongPoint Extent)
  644.     {
  645.         Rect        Temp;
  646.  
  647.         ERROR(MyGrafPtr != thePort,PRERR(ForceAbort,GrafErrMsg));
  648.         LongRectToShort(Start,Extent,&Temp);
  649.         FrameRect(&Temp);
  650.     }
  651.  
  652.  
  653. void            CWindow::LPaintRect(LongPoint Start, LongPoint Extent)
  654.     {
  655.         Rect        Temp;
  656.  
  657.         ERROR(MyGrafPtr != thePort,PRERR(ForceAbort,GrafErrMsg));
  658.         LongRectToShort(Start,Extent,&Temp);
  659.         PaintRect(&Temp);
  660.     }
  661.  
  662.  
  663. void            CWindow::LEraseRect(LongPoint Start, LongPoint Extent)
  664.     {
  665.         Rect        Temp;
  666.  
  667.         ERROR(MyGrafPtr != thePort,PRERR(ForceAbort,GrafErrMsg));
  668.         LongRectToShort(Start,Extent,&Temp);
  669.         EraseRect(&Temp);
  670.     }
  671.  
  672.  
  673. void            CWindow::LFrameOval(LongPoint Start, LongPoint Extent)
  674.     {
  675.         Rect        Temp;
  676.  
  677.         ERROR(MyGrafPtr != thePort,PRERR(ForceAbort,GrafErrMsg));
  678.         LongRectToShort(Start,Extent,&Temp);
  679.         FrameOval(&Temp);
  680.     }
  681.  
  682.  
  683. void            CWindow::LPaintOval(LongPoint Start, LongPoint Extent)
  684.     {
  685.         Rect        Temp;
  686.  
  687.         ERROR(MyGrafPtr != thePort,PRERR(ForceAbort,GrafErrMsg));
  688.         LongRectToShort(Start,Extent,&Temp);
  689.         PaintOval(&Temp);
  690.     }
  691.  
  692.  
  693. void            CWindow::LEraseOval(LongPoint Start, LongPoint Extent)
  694.     {
  695.         Rect        Temp;
  696.  
  697.         ERROR(MyGrafPtr != thePort,PRERR(ForceAbort,GrafErrMsg));
  698.         LongRectToShort(Start,Extent,&Temp);
  699.         EraseOval(&Temp);
  700.     }
  701.  
  702.  
  703. void            CWindow::LFrameRoundRect(LongPoint Start, LongPoint Extent, short OvalWidth, short OvalHeight)
  704.     {
  705.         Rect        Temp;
  706.  
  707.         ERROR(MyGrafPtr != thePort,PRERR(ForceAbort,GrafErrMsg));
  708.         LongRectToShort(Start,Extent,&Temp);
  709.         FrameRoundRect(&Temp,OvalWidth,OvalHeight);
  710.     }
  711.  
  712.  
  713. void            CWindow::LPaintRoundRect(LongPoint Start, LongPoint Extent, short OvalWidth, short OvalHeight)
  714.     {
  715.         Rect        Temp;
  716.  
  717.         ERROR(MyGrafPtr != thePort,PRERR(ForceAbort,GrafErrMsg));
  718.         LongRectToShort(Start,Extent,&Temp);
  719.         PaintRoundRect(&Temp,OvalWidth,OvalHeight);
  720.     }
  721.  
  722.  
  723. void            CWindow::LEraseRoundRect(LongPoint Start, LongPoint Extent, short OvalWidth, short OvalHeight)
  724.     {
  725.         Rect        Temp;
  726.  
  727.         ERROR(MyGrafPtr != thePort,PRERR(ForceAbort,GrafErrMsg));
  728.         LongRectToShort(Start,Extent,&Temp);
  729.         EraseRoundRect(&Temp,OvalWidth,OvalHeight);
  730.     }
  731.  
  732.  
  733. void            CWindow::SetPattern(Pattern ThePattern)
  734.     {
  735.         ERROR(MyGrafPtr != thePort,PRERR(ForceAbort,GrafErrMsg));
  736.         PenPat(ThePattern);
  737.     }
  738.  
  739.  
  740. void            CWindow::InvalidateLong(LongPoint Start, LongPoint Extent)
  741.     {
  742.         Rect            ShortOne;
  743.  
  744.         ERROR(MyGrafPtr != thePort,PRERR(ForceAbort,GrafErrMsg));
  745.         LongRectToShort(Start,Extent,&ShortOne);
  746.         Start.x = ShortOne.left;
  747.         Start.y = ShortOne.top;
  748.         Extent.x = ShortOne.right - ShortOne.left;
  749.         Extent.y = ShortOne.bottom - ShortOne.top;
  750.         SectLongRect(Start,Extent,ClipStart,ClipExtent,&Start,&Extent);
  751.         ShortOne.left = Start.x;
  752.         ShortOne.top = Start.y;
  753.         ShortOne.right = Start.x + Extent.x;
  754.         ShortOne.bottom = Start.y + Extent.y;
  755.         InvalRect(&ShortOne);
  756.     }
  757.  
  758.  
  759. void            CWindow::ScrollLong(LongPoint Start, LongPoint Extent, LongPoint Change)
  760.     {
  761.         RgnHandle        UpdateRegion;
  762.         RgnHandle        WhiteRegion;
  763.         Rect                TheRect;
  764.         RgnHandle        InvalidRegion;
  765.         RgnHandle        TempRgn;
  766.  
  767.         ERROR(MyGrafPtr != thePort,PRERR(ForceAbort,GrafErrMsg));
  768.         /* we constrain the range into a short integer.  This will not cause */
  769.         /* problems until we start getting REALLY BIG monitors. */
  770.         if ((Change.x < -32767) || (Change.x > 32767) || (Change.y < -32767)
  771.             || (Change.y > 32767))
  772.             {
  773.                 /* erase screen and invalidate nothing */
  774.                 LEraseRect(Start,Extent);
  775.                 return;
  776.             }
  777.         /* converting to a regular rect */
  778.         LongRectToShort(Start,Extent,&TheRect);
  779.         /* create update region */
  780.         UpdateRegion = NewRgn();
  781.         /* do the scroll */
  782.         ScrollRect(&TheRect,Change.x,Change.y,UpdateRegion);
  783.         /* we want to add to the update region any area that was already invalid */
  784.         InvalidRegion = NewRgn();
  785.         TempRgn = NewRgn();
  786.         RectRgn(InvalidRegion,&TheRect);
  787.         CopyRgn(InvalidRegion,TempRgn);
  788.         SectRgn(((WindowPeek)MyGrafPtr)->updateRgn,InvalidRegion,InvalidRegion);
  789.         OffsetRgn(InvalidRegion,Change.x,Change.y);
  790.         SectRgn(InvalidRegion,TempRgn,InvalidRegion);
  791.         DisposeRgn(TempRgn);
  792.         UnionRgn(InvalidRegion,UpdateRegion,UpdateRegion);
  793.         DisposeRgn(InvalidRegion);
  794.         /* it is assumed that the program will redraw the empty area created by scrolling. */
  795.         /* we only want to add the area created by overlapping windows. */
  796.         WhiteRegion = NewRgn();
  797.         if (Change.x >= 0)
  798.             {
  799.                 SetRectRgn(WhiteRegion,TheRect.left,TheRect.top,
  800.                     TheRect.left + Change.x,TheRect.bottom);
  801.             }
  802.          else
  803.             {
  804.                 SetRectRgn(WhiteRegion,TheRect.right + Change.x,
  805.                     TheRect.top,TheRect.right,TheRect.bottom);
  806.             }
  807.         DiffRgn(UpdateRegion,WhiteRegion,UpdateRegion);
  808.         if (Change.y >= 0)
  809.             {
  810.                 SetRectRgn(WhiteRegion,TheRect.left,TheRect.top,
  811.                     TheRect.right,TheRect.top + Change.y);
  812.             }
  813.          else
  814.             {
  815.                 SetRectRgn(WhiteRegion,TheRect.left,TheRect.bottom + Change.y,
  816.                     TheRect.right,TheRect.bottom);
  817.             }
  818.         DiffRgn(UpdateRegion,WhiteRegion,UpdateRegion);
  819. #if DOTHENAUGHTY
  820.         /* I have to do this since InvalRgn isn't working properly. */
  821.         UnionRgn(UpdateRegion,((WindowPeek)MyGrafPtr)->updateRgn,
  822.             ((WindowPeek)MyGrafPtr)->updateRgn);
  823. #endif
  824.         InvalRgn(UpdateRegion);
  825.         /* get rid of update region */
  826.         DisposeRgn(UpdateRegion);
  827.         DisposeRgn(WhiteRegion);
  828.     }
  829.  
  830.  
  831. void            CWindow::ScrollLongAndInvalidate(LongPoint Start, LongPoint Extent, LongPoint Change)
  832.     {
  833.         RgnHandle        UpdateRegion;
  834.         Rect                TheRect;
  835.         RgnHandle        InvalidRegion;
  836.         RgnHandle        TempRgn;
  837.  
  838.         ERROR(MyGrafPtr != thePort,PRERR(ForceAbort,GrafErrMsg));
  839.         if ((Change.x < -32767) || (Change.x > 32767) || (Change.y < -32767)
  840.             || (Change.y > 32767))
  841.             {
  842.                 /* if we scroll out of qd space, just erase & return */
  843.                 LEraseRect(Start,Extent);
  844.                 return;
  845.             }
  846.         /* converting to a regular rect */
  847.         LongRectToShort(Start,Extent,&TheRect);
  848.         /* create update region */
  849.         UpdateRegion = NewRgn();
  850.         /* do the scroll */
  851.         ScrollRect(&TheRect,Change.x,Change.y,UpdateRegion);
  852.         /* we want to add to the update region any area that was already invalid */
  853.         InvalidRegion = NewRgn();
  854.         TempRgn = NewRgn();
  855.         RectRgn(InvalidRegion,&TheRect);
  856.         CopyRgn(InvalidRegion,TempRgn);
  857.         SectRgn(((WindowPeek)MyGrafPtr)->updateRgn,InvalidRegion,InvalidRegion);
  858.         OffsetRgn(InvalidRegion,Change.x,Change.y);
  859.         SectRgn(InvalidRegion,TempRgn,InvalidRegion);
  860.         DisposeRgn(TempRgn);
  861.         UnionRgn(InvalidRegion,UpdateRegion,UpdateRegion);
  862.         DisposeRgn(InvalidRegion);
  863.         /* invalidate all bad areas */
  864. #if DOTHENAUGHTY
  865.         /* I have to do this since InvalRgn isn't working properly. */
  866.         UnionRgn(UpdateRegion,((WindowPeek)MyGrafPtr)->updateRgn,
  867.             ((WindowPeek)MyGrafPtr)->updateRgn);
  868. #endif
  869.         InvalRgn(UpdateRegion);
  870.         /* get rid of update region */
  871.         DisposeRgn(UpdateRegion);
  872.     }
  873.  
  874.  
  875. /********************************************************************************/
  876. /* utility routines */
  877.  
  878.  
  879. MyBoolean    CWindow::RectVisible(LongPoint Start, LongPoint Extent)
  880.     {
  881.         Rect        Temp;
  882.  
  883.         LongRectToShort(Start,Extent,&Temp);
  884.         return RectInRgn(&Temp,MyGrafPtr->visRgn);
  885.     }
  886.  
  887.  
  888. MyBoolean    CWindow::LongRectToShort(LongPoint Start, LongPoint Extent, Rect* ShortOne)
  889.     {
  890.         register    MyBoolean    Flag;
  891.  
  892.         Start.x += DrawingOrigin.x;
  893.         Start.y += DrawingOrigin.y;
  894.         Extent.x += Start.x;
  895.         Extent.y += Start.y;
  896.         Flag = True;
  897.         if (Start.x < -32767) {Start.x = -32767; Flag = False;}
  898.         if (Start.x > 32767) {Start.x = 32767; Flag = False;}
  899.         if (Extent.x < -32767) {Extent.x = -32767; Flag = False;}
  900.         if (Extent.x > 32767) {Extent.x = 32767; Flag = False;}
  901.         if (Start.y < -32767) {Start.y = -32767; Flag = False;}
  902.         if (Start.y > 32767) {Start.y = 32767; Flag = False;}
  903.         if (Extent.y < -32767) {Extent.y = -32767; Flag = False;}
  904.         if (Extent.y > 32767) {Extent.y = 32767; Flag = False;}
  905.         ShortOne->left = Start.x;
  906.         ShortOne->right = Extent.x;
  907.         ShortOne->top = Start.y;
  908.         ShortOne->bottom = Extent.y;
  909.         return Flag;
  910.     }
  911.  
  912.  
  913. /****************************************************************/
  914. /* Non-window object utility routines */
  915.  
  916.  
  917. Rect            RectOf(short x1, short y1, short x2, short y2)
  918.     {
  919.         Rect    Temp;
  920.  
  921.         Temp.left = x1;
  922.         Temp.top = y1;
  923.         Temp.right = x2;
  924.         Temp.bottom = y2;
  925.         return Temp;
  926.     }
  927.  
  928.  
  929. Point            PointOf(short x, short y)
  930.     {
  931.         Point    Temp;
  932.  
  933.         Temp.v = y;
  934.         Temp.h = x;
  935.         return Temp;
  936.     }
  937.  
  938.  
  939. LongPoint    LongPointOf(long x, long y)
  940.     {
  941.         LongPoint    Temp;
  942.  
  943.         Temp.x = x;
  944.         Temp.y = y;
  945.         return Temp;
  946.     }
  947.  
  948.  
  949. /* get a Rect from the resource file. */
  950. /* high word of RectID = ID of resource */
  951. /* low word of RectID = ID of rect within that resource */
  952. /* the resources are expected to be in big-endian format.  This code */
  953. /* should work even on little-endian processors */
  954. void        GetRect(ulong RectID, LongPoint* Start, LongPoint* Extent)
  955.     {
  956.         Handle        RectRes;
  957.         char*            RectList;
  958.         ulong            Scan;  /* scans the list by byte */
  959.         ushort        Count;
  960.         ushort        IDToFind;
  961.         LongPoint    Temp;
  962.  
  963.         ERROR(ResLoad == 0,PRERR(ForceAbort,"Automatic resource loading is disabled."));
  964.         RectRes = GetResource('∫Rct',(RectID >> 16) & 0x0000ffff);
  965.         if (RectRes == NIL)
  966.             {
  967.                 PRERR(ForceAbort,"GetRect couldn't load resource.");
  968.             }
  969.         ERROR(ResErr != noErr,PRERR(ForceAbort,"Resource Error occurred."));
  970.         HLock(RectRes);
  971.         RectList = *RectRes;  /* dereference */
  972.         IDToFind = 0x0000ffff & RectID;  /* isolate local ID */
  973.         Scan = 2;  /* start with the 2nd word */
  974.         /* getting number of items to do (big-endian) */
  975.         Count = ((uchar*)RectList)[1] + (256 * ((uchar*)RectList)[0]);
  976.         while (Count > 0)
  977.             {
  978.                 if ((((uchar*)RectList)[Scan] * 256) + (((uchar*)RectList)[Scan + 1])
  979.                     == IDToFind)
  980.                     {
  981.                         char*            BaseAddr;
  982.  
  983.                         /* we've found it--copy it out */
  984.                         BaseAddr = (char*)((((StrLen((char*)(RectList + Scan + sizeof(short))))
  985.                             & (~1)) + 2) + (char*)RectList +    Scan + sizeof(short));
  986.                         HUnlock(RectRes);
  987.                         (*Start).x = ((signed char)*(BaseAddr++) * 256) + (uchar)*(BaseAddr++);
  988.                         (*Start).y = ((signed char)*(BaseAddr++) * 256) + (uchar)*(BaseAddr++);
  989.                         (*Extent).x = ((signed char)*(BaseAddr++) * 256) + (uchar)*(BaseAddr++);
  990.                         (*Extent).y = ((signed char)*(BaseAddr++) * 256) + (uchar)*(BaseAddr++);
  991.                         return;
  992.                     }
  993.                 /* skip to next item */
  994.                 Scan +=
  995.                     ((   (StrLen((char*)(RectList + Scan + sizeof(short))))
  996.                     & (~1)) + 2) + sizeof(short) + 4*sizeof(short);
  997.                 Count -= 1;  /* decrement the counter */
  998.             }
  999.         HUnlock(RectRes);
  1000.         PRERR(ForceAbort,"GetRect couldn't find rectangle in resource.");
  1001.     }
  1002.  
  1003.  
  1004. MyBoolean    LongPtInRect(LongPoint ThePoint, LongPoint Start, LongPoint Extent)
  1005.     {
  1006.         if (ThePoint.x < Start.x) return False;
  1007.         if (ThePoint.x >= Start.x + Extent.x) return False;
  1008.         if (ThePoint.y < Start.y) return False;
  1009.         if (ThePoint.y >= Start.y + Extent.y) return False;
  1010.         return True;
  1011.     }
  1012.  
  1013.  
  1014. /* returns new Start */
  1015. LongPoint    CenterRect(LongPoint Extent, LongPoint ContainerExtent)
  1016.     {
  1017.         LongPoint    NewStart;
  1018.  
  1019.         NewStart.x = (ContainerExtent.x - Extent.x) / 2;
  1020.         NewStart.y = (ContainerExtent.y - Extent.y) / 3;
  1021.         if (NewStart.y < 20 + GetMBarHeight())
  1022.             {
  1023.                 NewStart.y = 20 + GetMBarHeight();
  1024.             }
  1025.         return NewStart;
  1026.     }
  1027.  
  1028.  
  1029. LongPoint    AlertCenterRect(LongPoint Extent, LongPoint ContainerExtent)
  1030.     {
  1031.         LongPoint    NewStart;
  1032.  
  1033.         NewStart.x = (ContainerExtent.x - Extent.x) / 2;
  1034.         NewStart.y = (ContainerExtent.y / 3) - Extent.y;
  1035.         if (NewStart.y < 40)
  1036.             {
  1037.                 NewStart.y = 40;
  1038.             }
  1039.         return NewStart;
  1040.     }
  1041.  
  1042.  
  1043. LongPoint    GetLongMouseLoc(void)
  1044.     {
  1045.         Point                MouseLoc;
  1046.         LongPoint        Result;
  1047.  
  1048.         GetMouse(&MouseLoc);
  1049.         LocalToGlobal(&MouseLoc);
  1050.         Result.x = MouseLoc.h;
  1051.         Result.y = MouseLoc.v;
  1052.         return Result;
  1053.     }
  1054.  
  1055.  
  1056. short            GetFontID(PString FontName)
  1057.     {
  1058.         short            FontID;
  1059.  
  1060.         GetFNum(FontName,&FontID);
  1061.         return FontID;
  1062.     }
  1063.  
  1064.  
  1065. void            SectLongRect(LongPoint Start1, LongPoint Extent1, LongPoint Start2,
  1066.                         LongPoint Extent2, register LongPoint* S, register LongPoint* E)
  1067.     {
  1068.         /* normalize the rectangles */
  1069.         if (Extent1.x < 0)
  1070.             {
  1071.                 Start1.x += Extent1.x;
  1072.                 Extent1.x = -Extent1.x;
  1073.             }
  1074.         if (Extent1.y < 0)
  1075.             {
  1076.                 Start1.y += Extent1.y;
  1077.                 Extent1.y = -Extent1.y;
  1078.             }
  1079.         if (Extent2.x < 0)
  1080.             {
  1081.                 Start2.x += Extent2.x;
  1082.                 Extent2.x = -Extent2.x;
  1083.             }
  1084.         if (Extent2.y < 0)
  1085.             {
  1086.                 Start2.y += Extent2.y;
  1087.                 Extent2.y = -Extent2.y;
  1088.             }
  1089.         /* constrain topleft corner */
  1090.         if (Start1.x > Start2.x)
  1091.             {
  1092.                 S->x = Start1.x;
  1093.             }
  1094.          else
  1095.             {
  1096.                 S->x = Start2.x;
  1097.             }
  1098.         if (Start1.y > Start2.y)
  1099.             {
  1100.                 S->y = Start1.y;
  1101.             }
  1102.          else
  1103.             {
  1104.                 S->y = Start2.y;
  1105.             }
  1106.         /* constrain bottomright corner */
  1107.         if (Start1.x+Extent1.x > Start2.x+Extent2.x)
  1108.             {
  1109.                 E->x = (Start2.x+Extent2.x) - S->x;
  1110.             }
  1111.          else
  1112.             {
  1113.                 E->x = (Start1.x+Extent1.x) - S->x;
  1114.             }
  1115.         if (Start1.y+Extent1.y > Start2.y+Extent2.y)
  1116.             {
  1117.                 E->y = (Start2.y+Extent2.y) - S->y;
  1118.             }
  1119.          else
  1120.             {
  1121.                 E->y = (Start1.y+Extent1.y) - S->y;
  1122.             }
  1123.     }
  1124.  
  1125.  
  1126. LongPoint    MainScreenSize(void)
  1127.     {
  1128.         return LongPointOf(screenBits.bounds.right - screenBits.bounds.left,
  1129.             screenBits.bounds.bottom - screenBits.bounds.top);
  1130.     }
  1131.  
  1132.  
  1133. PicHandle    GetPic(short PicID)
  1134.     {
  1135.         PicHandle        Temp;
  1136.  
  1137.         ERROR(ResLoad == 0,PRERR(ForceAbort,"Automatic resource loading is disabled."));
  1138.         Temp = (PicHandle)GetResource('PICT',PicID);
  1139.         ERROR(Temp==NIL,PRERR(ForceAbort,"GetPic: Couldn't find PICT"));
  1140.         ERROR(ResErr != noErr,PRERR(ForceAbort,"Resource Error occurred."));
  1141.         return Temp;
  1142.     }
  1143.